<template>
    <div class="pl-26px text-14px text-#999">完整填写产品基本信息，是关键词推广的基本前提</div>
    <div class="pl-26px pt-26px">
        <el-form ref="ruleFormRef" :model="props.ruleForm" :rules="rules" label-width="auto">
            <el-form-item label="产品名称" prop="name">
                <div class="w-400px">
                    <el-input ref="nameRef" v-model="props.ruleForm.name" placeholder="请输入产品名称" />
                </div>
            </el-form-item>
            <el-form-item label="产品型号" prop="model">
                <div class="w-400px">
                    <el-input ref="modelRef" v-model="props.ruleForm.model" placeholder="请输入产品型号" />
                </div>
            </el-form-item>
            <el-form-item label="产品品牌" prop="brand">
                <div class="w-400px">
                    <el-input ref="brandRef" v-model="props.ruleForm.brand" placeholder="请输入产品品牌" />
                </div>
            </el-form-item>
            <el-form-item label="产品产地" prop="area">
                <ProvinceCitySelector ref="provinceCitySelector" v-model:province="props.ruleForm.province"
                    v-model:city="props.ruleForm.city" />
            </el-form-item>
            <el-form-item label="产品简介" prop="intro">
                <div class="w-400px">
                    <el-input ref="introRef" v-model="props.ruleForm.intro" type="textarea" :rows="8"
                        placeholder="请输入产品简介" />
                </div>
            </el-form-item>
            <el-form-item label="上传图片" prop="images">
                <div class="flex flex-col">
                    <div class="flex">
                        <el-upload v-for="(item, index) in props.ruleForm.images" :key="item.url"
                            :id="'upload-' + index" class="mr-12px upload-image"
                            :action="Url + '/api/ProductApi/FileUploadimg'"
                            :show-file-list="false" :on-success="handleAvatarSuccess"
                            :before-upload="beforeAvatarUpload">
                            <img v-if="item.url" :src="item.url" class="avatar" @click="isPreview = !isPreview" />
                            <div class="flex flex-col flex-center text-14px text-#999999 upload-btn" v-else>
                                <svg-icon size="30px" icon-class="add-fill"></svg-icon>选择图片
                            </div>
                            <svg-icon v-if="item.url" size="20px" icon-class="close-circle-fill" class="del"
                                @click="handleDelImg(index, $event)"></svg-icon>
                            <svg-icon title="替换图片" v-if="item.url" size="20px" icon-class="refresh-fill" class="replace"
                                @click="handleReplaceImg(index)"></svg-icon>
                        </el-upload>
                    </div>
                    <div class="text-12px text-#999 mt-5px">可上传1-5张图片（上传图片必须为jpg、gif、png格式文件且文件大小不超过3M，图片勿
                        带联系方式或打水印，否则本站将自动删除产品图片）</div>
                </div>
            </el-form-item>
            <el-form-item label="产品详细内容" prop="content">
                <div class="w-90%">
                    <!-- editor-id要唯一 -->
                    <vue-ueditor-wrap v-model="props.ruleForm.content" :editor-id="editor" :config="editorConfig"
                        :editorDependencies="['ueditor.config.js', 'ueditor.all.js']" />
                </div>
                <div class="text-12px text-#999 mt-5px">为了保证关键词排名效果，请您不要填写任何联系信息（如联系人、联系电话、传真、手 机、邮箱、网址等等 </div>
            </el-form-item>
            <el-form-item>
                <div class="pl-106px pb-40px">
                    <el-button :loading="loading" type="primary" @click="handleNext(ruleFormRef)">下一步</el-button>
                </div>
            </el-form-item>

        </el-form>
        <el-dialog v-model="isPreview">
            <img w-full :src="props.ruleForm.images" alt="Preview Image" />
        </el-dialog>
    </div>
</template>

<script setup lang="ts">
import type { UploadProps } from 'element-plus'
import ProvinceCitySelector from '@/components/ProvinceCitySelector/index.vue'
import { editorContentCheckApi, deleteWordsCheckApi, sensitiveWordsCheckApi } from '@/api/b2b/index'
import { normalStr, violationStr } from '@/utils/checkStr'
import { findMatchingElements, highlightMatches, debounce } from '@/utils/index'
import { confirmMessageBox } from '@/utils/elMessageBox'
import { CircleCloseFilled, WarningFilled } from '@element-plus/icons-vue'

const props = defineProps<{
    modelValue: number
    ruleForm: any,
    editor: string
}>()

// 使用 computed + watch 实现双向绑定效果
const step = ref(props.modelValue)

const Url = import.meta.env.VITE_APP_UPLOAD_URL

watch(
    () => props.modelValue,
    (newVal) => {
        if (typeof newVal === 'number') {
            step.value = newVal
        }
    }
)

const emit = defineEmits(['update:modelValue', 'step-1-complete'])

const ruleFormRef = ref()
const nameRef = ref()
const modelRef = ref()
const brandRef = ref()
const introRef = ref()
const isError = ref(false)
const loading = ref(false)
const isIntro = ref(false)

const rules = reactive({    //注意validator 其他属性不起作用，要在validator中处理
    name: [
        { min: 3, max: 35, required: true, message: '请输入产品名称', trigger: 'blur', validator: checkName }
    ],
    model: [
        { min: 3, max: 50, trigger: 'blur', validator: checkModel }
    ],
    brand: [
        { min: 3, max: 50, trigger: 'blur', validator: checkBrand }
    ],
    intro: [
        { required: true, message: '请输入产品简介', trigger: 'blur', validator: checkIntro }
    ],
    content: [
        { required: true, message: '请输入产品详细内容', validator: checkContent }
    ],
})

const provinceCitySelector = ref<InstanceType<typeof ProvinceCitySelector> & ProvinceCitySelectorInstance | null>(null)

const editorConfig = {
    // 后端服务地址，后端处理参考
    // https://open-doc.modstart.com/ueditor-plus/backend.html
    serverUrl: import.meta.env.VITE_APP_EDITOR_URL,
    UEDITOR_HOME_URL: '/static/UEditorPlus/',
    UEDITOR_CORS_URL: '/static/UEditorPlus/',
    /* 上传图片配置项 */
    imageActionName: 'uploadFile' /* 执行上传图片的action名称 */,
    imageFieldName: 'file' /* 提交的图片表单名称 */,
    imageMaxSize: 2048000 /* 上传大小限制，单位B */,
    imageAllowFiles: ['.png', '.jpg', '.jpeg', '.gif', '.bmp'] /* 上传图片格式显示 */,
    imageCompressEnable: true /* 是否压缩图片,默认是true */,
    imageCompressBorder: 1600 /* 图片压缩最长边限制 */,
    imageInsertAlign: 'none' /* 插入的图片浮动方式 */,
    imageUrlPrefix: '' /* 图片访问路径前缀 */,
    imagePathFormat: '' /* 上传保存路径,可以自定义保存路径和文件名格式 */,
    autoHeightEnabled: false,

    serverHeaders: {
        'Authorization': sessionStorage.getItem('X-token')
    },
}

let imgArr = <string[]>[]
const isPreview = ref(false)

const handleAvatarSuccess: UploadProps['onSuccess'] = (
    response,
    uploadFile
) => {
    if (response.code === 200) {
        ElMessage.success(response.message)
        imgArr.push(response.imgpath)
        imgArr.forEach((item, index) => {
            props.ruleForm.images[index].url = item
        })
    }

}

const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
    const validTypes = ['image/jpeg', 'image/gif', 'image/png']
    if (!validTypes.includes(rawFile.type)) {
        ElMessage.error('上传图片必须为 JPG / GIF / PNG 格式!')
        return false
    } else if (rawFile.size / 1024 / 1024 > 3) {
        ElMessage.error('上传图片不能超过 3MB!')
        return false
    }
    return true
}

// async function handleNext(formEl: any) {
//     loading.value = true
//     if (!formEl) return
//     await formEl.validate(async (valid: boolean) => {
//         console.log('valid', valid)
//         if (valid) {
//             if (provinceCitySelector.value) {
//                 props.ruleForm.province = provinceCitySelector.value.selectedProvince?.name
//                 props.ruleForm.city = provinceCitySelector.value.selectedCity
//             }

//             //第一步检测必删词
//             //第二步检测敏感词

//             //检测产品简介
//             try {
//                 const res: ResType = await sensitiveWordsCheckApi({
//                     txt: props.ruleForm.name,
//                     content: props.ruleForm.intro
//                 })
//                 if (res.code === 200) {
//                     isError.value = false
//                     return true
//                 }
//             } catch (error: any) {
//                 if (error.response && error.response.status === 405) {
//                     confirmMessageBox(WarningFilled, `您发布的信息中含有类似虚假宣传、违禁词等敏感词，或含有本平台规定不得发布的医疗器械、 诊断试剂、药品等相关内容：(如："${error.response.data.message}")，从规避风险角度，建议修改后提交。`, '继续发布', '立即修改', () => {
//                         loading.value = false
//                         isError.value = true

//                         checkAll()
//                     }, () => {
//                         loading.value = false
//                         isError.value = true
//                         return false
//                     })
//                 }
//                 return false
//             }

//         } else {
//             loading.value = false
//             console.log('error submit!')
//         }
//     })
// }

// async function checkAll() {
//     try {
//         const newStep = step.value + 1
//         step.value = newStep
//         // 检测输入内容
//         props.ruleForm.checkStr = props.ruleForm.name + props.ruleForm.model + props.ruleForm.brand + props.ruleForm.intro

//         //必删词检测
//         const res: ResType = await deleteWordsCheckApi({
//             txt: props.ruleForm.checkStr,
//             content: props.ruleForm.content
//         })
//         console.log(res)
//         if (res.code === 200) {
//             const isSensitive = await sensitiveWordsCheck(props.ruleForm.content, 'content')
//             console.log(isSensitive)
//             if (isSensitive) {
//                 loading.value = false
//                 emit('update:modelValue', newStep)
//                 emit('step-1-complete', props.ruleForm)
//                 return true
//             } else {
//                 return false
//             }
//         }
//     } catch (error: any) {
//         if (error.response && error.response.status === 405) {
//             markError(props.ruleForm.content, error.response.data.message)
//             confirmMessageBox(CircleCloseFilled, `您发布的信息中含有虚假宣传、违禁词等敏感词，或含有本平台规定不得发布的医疗器械、 诊断试剂、药品等相关内容：(如：${error.response.data.message})，请检查修改后提交。`,)
//         }
//         loading.value = false
//         return false
//     }
// }

function handleDelImg(index: number, event: MouseEvent) {
    event.stopPropagation()
    confirmMessageBox(WarningFilled, '您确定要删除此图片吗？', '', '', () => {
        imgArr.splice(index, 1)
        props.ruleForm.images[index].url = ''
    })
}

function handleReplaceImg(index: number) {
    const elementId = 'upload-' + index;
    const uploadElement = document.getElementById(elementId);

    // 判断元素是否存在
    if (uploadElement) {
        uploadElement.click();
    } else {
        console.warn(`Element with id "${elementId}" not found`);
    }
}

function checkName(rule: any, value: any, callback: any) {
    if (value === '') {
        callback(new Error('请输入产品名称'))
    } else {
        if (value.length > 35) {
            callback(new Error('产品名称不能超过35个字符'))
        }
        const arr = findMatchingElements(value, normalStr.concat(violationStr))
        if (arr.length) {
            confirmMessageBox(CircleCloseFilled, '产品名称里不能包含 ' + arr[0] + ' 请修改', '', '', () => {
                nameRef.value.focus()
            })
            callback(new Error()) // 必须调用 callback 来通知校验失败
        } else {
            callback() // 校验通过
        }
    }
}

function checkModel(rule: any, value: any, callback: any) {
    if (value) {
        if (value.length > 50) {
            callback(new Error('产品型号不能超过50个字符'))
        }
        const arr = findMatchingElements(value, violationStr)
        if (arr.length) {
            confirmMessageBox(CircleCloseFilled, '产品型号里不能包含 ' + arr[0] + ' 请修改', '', '', () => {
                modelRef.value.focus()
            })
            callback(new Error())
        } else {
            callback() // 校验通过
        }
    } else {
        callback()

    }
}

function checkBrand(rule: any, value: any, callback: any) {
    if (value) {
        if (value.length > 100) {
            callback(new Error('产品品牌不能超过50个字符'))
        }
        const arr = findMatchingElements(value, violationStr)
        if (arr.length) {
            confirmMessageBox(CircleCloseFilled, '产品品牌里不能包含 ' + arr[0] + ' 请修改', '', '', () => {
                brandRef.value.focus()
            })
            callback(new Error())
        } else {
            callback() // 校验通过
        }
    } else {
        callback()

    }
}
async function checkIntro(rule: any, value: any, callback: any) {
    if (value === '') {
        callback(new Error('请输入产品简介'))
    } else {
        const arr = findMatchingElements(value, violationStr)
        if (arr.length) {
            confirmMessageBox(CircleCloseFilled, '产品简介里不能包含 ' + arr[0] + ' 请修改', '', '', () => {
                introRef.value.focus()
            })
            callback(new Error())
        } else {
            callback()
        }
    }
}
async function checkContent(rule: any, value: any, callback: any) {
    if (value === '') {
        callback(new Error('请输入产品详细内容'))
    } else {
        try {
            //内容检测（字数/后端违规词）
            const res: ResType = await editorContentCheckApi({ content: value });
            if (res.code === 200) {
                callback()
            }
        } catch (error: any) {
            if (error.response.data.data) {
                markError(value, error.response.data.data)
            }
            if (error.response && error.response.status === 405) {
                confirmMessageBox(CircleCloseFilled, error.response.data.message, '', '', () => {
                    loading.value = false
                    isError.value = true
                    return false
                })
                callback(new Error(error.response.data.message))
            }
        }
    }
}

// 提取 debounced 函数，并在 watch 中复用它
const debouncedCheckContent = debounce(async (newContent: string) => {
    if (!isError.value) {
        const isHas = violationStr.some(item => newContent.includes(item))
        if (isHas) {
            //检测违规词
            const highlightedContent = highlightMatches(newContent, violationStr);
            props.ruleForm.content = highlightedContent;
            isError.value = true

            confirmMessageBox(CircleCloseFilled, `您发布的信息中不能包含 '医用','医疗器械','手术器械' 请检查修改后提交`, '', '', () => {
                isError.value = false
            })
            return false
        } else {
            try {
                //内容检测（字数/后端违规词）
                const res: ResType = await editorContentCheckApi({ content: newContent });
                if (res.code === 200) {
                    return true
                }
            } catch (error: any) {
                if (error.response.data.data) {
                    markError(newContent, error.response.data.data)
                }
                if (error.response && error.response.status === 405) {
                    confirmMessageBox(CircleCloseFilled, error.response.data.message, '', '', () => {
                        loading.value = false
                        isError.value = true
                        return false
                    })
                }
                return false
            }
        }
    }
}, 300);

async function sensitiveWordsCheck(content: string, type: string = 'content') {
    //检测敏感词
    try {
        const res: ResType = await sensitiveWordsCheckApi({
            txt: props.ruleForm.name,
            content: content
        })
        if (res.code === 200) {
            isError.value = false
            loading.value = false
            return true
        }
    } catch (error: any) {
        if (error.response && error.response.status === 405) {
            if (type == 'content') {
                markError(content, error.response.data.message)
                return new Promise((resolve, reject) => {
                    confirmMessageBox(WarningFilled, `您发布的产品详细内容中含有类似虚假宣传、违禁词等敏感词，或含有本平台规定不得发布的医疗器械、 诊断试剂、药品等相关内容：(如："${error.response.data.message}")，从规避风险角度，建议修改后提交。`, '继续发布', '立即修改', () => {
                        loading.value = false
                        resolve(true)
                    }, () => {
                        loading.value = false
                        reject(false)
                    })
                })
            }else if(type === 'intro'){
                return new Promise((resolve, reject) => {
                    confirmMessageBox(WarningFilled, `您发布的产品简介中含有类似虚假宣传、违禁词等敏感词，或含有本平台规定不得发布的医疗器械、 诊断试剂、药品等相关内容：(如："${error.response.data.message}")，从规避风险角度，建议修改后提交。`, '继续发布', '立即修改', () => {
                        loading.value = false
                        resolve(true)
                    }, () => {
                        loading.value = false
                        reject(false)
                    })
                })
            }
        }
        return false
    }
}

async function deleteWordsCheck() {
    try {
        // 检测输入内容
        props.ruleForm.checkStr = props.ruleForm.name + props.ruleForm.model + props.ruleForm.brand + props.ruleForm.intro

        //必删词检测
        const res: ResType = await deleteWordsCheckApi({
            txt: props.ruleForm.checkStr,
            content: props.ruleForm.content
        })
        if (res.code === 200) {
            loading.value = false
            return true
        }
    } catch (error: any) {
        if (error.response && error.response.status === 405) {
            markError(props.ruleForm.content, error.response.data.message)
            return new Promise((resolve, reject) => {
                confirmMessageBox(CircleCloseFilled, `您发布的信息中含有虚假宣传、违禁词等敏感词，或含有本平台规定不得发布的医疗器械、 诊断试剂、药品等相关内容：(如：${error.response.data.message})，请检查修改后提交。`,'','', () => {
                    loading.value = false
                    resolve(false)
                }, () => {
                    loading.value = false
                    reject(false)
                })
            })
            
        }
    }
}

async function handleNext(formEl: any) {
    loading.value = true
    if (!formEl) return
    await formEl.validate(async (valid: boolean) => {
        if (valid) {
            if (provinceCitySelector.value) {
                props.ruleForm.province = provinceCitySelector.value.selectedProvince?.name
                props.ruleForm.city = provinceCitySelector.value.selectedCity
            }
            //第一步检测必删词
            const isDeleteWordsCheck = await deleteWordsCheck()
            if(isDeleteWordsCheck){
                //第二步检测敏感词
                const isCheckIntro = await sensitiveWordsCheck(props.ruleForm.intro,'intro')
                if(isCheckIntro){
                    const isCheckContent = await sensitiveWordsCheck(props.ruleForm.content,'content')
                    if(isCheckContent){
                        const newStep = step.value + 1
                        step.value = newStep
                        emit('update:modelValue', newStep)
                        emit('step-1-complete', props.ruleForm)
                    }
                }
            }
            
        } else {
            loading.value = false
            console.log('error submit!')
        }
    })
}

//敏感词错误提示及标红展示
function markError(content: string, word: string) {
    let sensitiveWords = <string[]>[]
    if (word.includes('|')) {
        sensitiveWords = word.split('|')
    } else {
        sensitiveWords.push(word)
    }
    const highlightedContent = highlightMatches(content, sensitiveWords)
    props.ruleForm.content = highlightedContent;
}

watch(
    () => props.ruleForm.content,
    (newContent) => {
        debouncedCheckContent(newContent)
    }
);

onMounted(() => {
    //给地区选择器赋值
    if (provinceCitySelector.value) {
        const selector = provinceCitySelector.value
        selector.selectedProvince.name = props.ruleForm.province
        selector.selectedCity = props.ruleForm.city
    }
})
</script>

<style scoped></style>